<?php


namespace App\Repositories;


use App\Models\Tally as Model;
use App\Models\TallyDetail;
use App\Traits\CodeTrait;
use App\Traits\Logs;
use Exception;
use LTools\Repositories\RepositoryAbstract;

class Tally extends RepositoryAbstract
{
    use CodeTrait, Logs;

    /**
     * Tally constructor.
     * @param Model $tally
     * @author luffyzhao@vip.126.com
     */
    public function __construct(Model $tally)
    {
        $this->model = $tally;
    }

    /**
     * @param array $attributes
     * @param int|null $perPage
     * @param array $columns
     * @param string $pageName
     * @param int|null $page
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     * @author luffyzhao@vip.126.com
     */
    public function paginate(array $attributes, int $perPage = null, array $columns = ['*'], $pageName = 'page', int $page = null)
    {
        return $this->model->with(['product', 'warehousing'])->where(
            $attributes
        )->paginate($perPage, $columns, $pageName, $page);
    }

    /**
     * @param array $attributes
     * @return bool|\Illuminate\Database\Eloquent\Model
     * @author luffyzhao@vip.126.com
     */
    public function create(array $attributes = [])
    {
        $attributes['code'] = $this->unique(7, 'T' . date('Ymd'));
        /** @var Model $model */
        $model = parent::create($attributes);
        // 日志
        $this->recordLogs($model, '创建理货单');
    }

    /**
     * @param $id
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|null
     * @author luffyzhao@vip.126.com
     */
    public function show($id)
    {
        return $this->model->with(['product', 'warehousing', 'details', 'logs.user'])->find($id);
    }

    /**
     * @param $id
     * @return Model
     * @throws Exception
     * @throws \Throwable
     * @author luffyzhao@vip.126.com
     */
    public function confirm($id)
    {
        /** @var Model $model */
        $model = $this->model->newQuery()->where('id', '=', $id)->lockForUpdate()->first();
        if ($model->getAttribute('status') === 0) {
            $model->setAttribute('status', 1);
            $model->saveOrFail();

            // 日志
            $this->recordLogs($model, '确认理货单');

            return $model;
        }
        throw new Exception('理货单状态不正确不能确认');
    }

    /**
     * @param $id
     * @return Model
     * @throws Exception
     * @throws \Throwable
     * @author luffyzhao@vip.126.com
     */
    public function complete($id)
    {
        /** @var Model $model */
        $model = $this->model->newQuery()->where('id', '=', $id)->lockForUpdate()->first();
        if ($model->getAttribute('status') === 1) {
            $quantity = $model->details()->sum('quantity');
            $model->setAttribute('send', $quantity);
            $model->setAttribute('status', 2);
            $model->saveOrFail();

            // 理货数据异常
            if ($quantity - $model->getAttribute('quantity') !== 0) {
                $model->product->inventory()->increment('anomalous', $quantity - $model->getAttribute('quantity'));
            }
            // 来货为 0 的不上架
            if ($model->getAttribute('quantity') === 0) {
                return $model;
            }
            // 添加上架单
            $model->details->each(function (TallyDetail $item) use ($model) {
                /** @var Shelves $shelves */
                $shelves = app(Shelves::class);
                $shelves->create(array_merge(
                    $model->only(['product_id', 'warehousing_id']),
                    $item->only(['tally_id', 'barcode', 'quantity', 'batch', 'attribute'])
                ));
            });

            // 日志
            $this->recordLogs($model, '完成理货单');

            return $model;
        }
        throw new Exception('理货单状态不正确不能完成');
    }

    /**
     * @param $id
     * @param array $attributes
     * @return Model
     * @throws Exception
     * @author luffyzhao@vip.126.com
     */
    public function storeDetail($id, array $attributes = [])
    {
        /** @var Model $model */
        $model = $this->model->newQuery()->where('id', '=', $id)->lockForUpdate()->first();
        if ($model->getAttribute('status') === 1) {
            $model->details()->create($attributes);

            // 日志
            $this->recordLogs($model, '理货单添加明细');

            return $model;
        }
        throw new Exception('理货单状态不正确不能添加明细');
    }

    /**
     * @param $id
     * @param $detailId
     * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Query\Builder|object|null
     * @throws Exception
     * @author luffyzhao@vip.126.com
     */
    public function destroyDetail($id, $detailId)
    {
        /** @var Model $model */
        $model = $this->model->newQuery()->where('id', '=', $id)->lockForUpdate()->first();
        if ($model->getAttribute('status') === 1) {
            $model->details()->where('id', '=', $detailId)->delete();

            // 日志
            $this->recordLogs($model, '理货单删除明细');

            return $model;
        }
        throw new Exception('理货单状态不正确不能删除明细');
    }
}
